package com.dhl.fin.api.service;

import com.dhl.fin.api.common.dto.QueryDto;
import com.dhl.fin.api.common.service.CommonService;
import com.dhl.fin.api.common.util.*;
import com.dhl.fin.api.domain.BankAccount;
import com.dhl.fin.api.domain.Family;
import com.dhl.fin.api.enums.BankAccountStatusEnum;
import com.dhl.fin.api.enums.FamilyAliasNameEnum;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import com.dhl.fin.api.util.NumberGenerate;

import java.util.*;

/**
 * @author CuiJianbo
 * @since 2025/3/16
 */
@Service
@Transactional(rollbackFor = Exception.class)
public class FamilyService extends CommonService<Family> {

    @Autowired
    private BankAccountService bankAccountService;

    @Autowired
    private FamilyConfigService familyConfigService;

    public String getFamilyUnicode(String accountCode) throws Exception {
        Family family = get(QueryDto.builder()
                .available()
                .addWhere("wx_account_code='" + accountCode + "'")
                .addWhere("bind_wx = 1").build());
        if (ObjectUtil.notNull(family)) {
            return family.getUnicode();
        } else {
            return UUID.randomUUID().toString();
        }
    }

    public Integer getFamilyOwner(String accountCode) throws Exception {
        Family family = get(QueryDto.builder().available()
                .addWhere("wx_account_code='" + accountCode + "'")
                .addWhere("bind_wx = 1")
                .build());
        if (ObjectUtil.notNull(family)) {
            return family.getOwner();
        } else {
            return -1;
        }
    }

    public Family getLoginUserInfo() throws Exception {
        String accountCode = WebUtil.getLoginUser().getUuid();
        Family family = get(QueryDto.builder().available().addWhere("wx_account_code='" + accountCode + "'").addWhere("bind_wx = 1").build());
        if (ObjectUtil.notNull(family)) {
            return family;
        } else {
            return null;
        }
    }

    public String unbindWx(Long id) throws Exception {

        deleteById(id);

        return UUID.randomUUID().toString();

    }

    @Override
    public String validate(Family domain) throws Exception {

        if ((domain.getMemberAlias().equals(FamilyAliasNameEnum.FATHER.getName()) || domain.getMemberAlias().equals(FamilyAliasNameEnum.MOTHER.getName())) && domain.getBindWx() == 1) {
            String wxAccountCode = WebUtil.getLoginUser().getUuid();
            Family family = get(QueryDto.builder().available().addWhereWhen("id != " + domain.getId(), ObjectUtil.notNull(domain.getId())).addWhere("wx_account_code='" + wxAccountCode + "'").addWhere("bind_wx = 1").build());
            if (ObjectUtil.notNull(family)) {
                return "微信号已被绑定";
            }
        }

        return super.validate(domain);
    }

    @Override
    public void beforeSave(Family domain) throws Exception {
        String accountCode = WebUtil.getLoginUser().getUuid();

        if (ObjectUtil.isNull(domain.getOwner())) {
            domain.setOwner(0);
        }
        if (ObjectUtil.isNull(domain.getBindWx())) {
            domain.setBindWx(0);
        }

        // 新增父母信息的场景
        if (domain.getMemberAlias().equals(FamilyAliasNameEnum.FATHER.getName()) || domain.getMemberAlias().equals(FamilyAliasNameEnum.MOTHER.getName())) {

            if (domain.getBindWx() > 0) {
                domain.setWxAccountCode(accountCode);
            }

            Family family = get(QueryDto.builder().available().addWhere("wx_account_code='" + accountCode + "'").addWhere("bind_wx = 0").build());

            if (ObjectUtil.notNull(family)) {
                domain.setId(family.getId());
                domain.setBindWx(1);
                domain.setCreateTime(DateUtil.getSysTime());
                domain.setCreateUser(accountCode);
            }

            //新增加家庭
            if (ObjectUtil.isNull(domain.getId())) {
                if (StringUtil.isEmpty(domain.getUnicode())) {
                    domain.setUnicode(UUID.randomUUID().toString());
                }
                familyConfigService.initFamilyConfig(domain.getUnicode());
            }
        }


        //新增小孩信息的场景
        if (domain.getMemberAlias().equals("小孩")) {

            if (ObjectUtil.notNull(domain.getBankAccount().getId())) {
                BankAccount bankAccount = bankAccountService.get(domain.getBankAccount().getId());
                bankAccount.setCardName(domain.getBankAccount().getCardName());
                bankAccount.setCardImg(domain.getBankAccount().getCardImg());
                bankAccount.setChildName(domain.getMemberName());
                bankAccountService.updateBySelective(bankAccount);
            } else {
                BankAccount bankAccount1 = domain.getBankAccount();
                bankAccount1.setFamilyUnicode(domain.getUnicode());
                bankAccount1.setChildName(domain.getMemberName());
                bankAccount1.setCurrentBalance(0.0);
                bankAccount1.setTotalInterestIncome(0.0);
                bankAccount1.setCardNumber(NumberGenerate.generateBankCardNumber());
                bankAccount1.setStatus(BankAccountStatusEnum.USED.getCode());
                bankAccount1.setExpireDate(DateUtil.getDate("2999-01-01"));
                bankAccountService.saveOrUpdate(bankAccount1);
            }

            List<Family> families = select(QueryDto.builder().available()
                    .addWhere("unicode='" + domain.getUnicode() + "'")
                    .addWhere("member_alias not in ('爸爸','妈妈')")
                    .addWhereWhen("id != " + domain.getId(), ObjectUtil.notNull(domain.getId())).addOrder("birthday").build());
            if (CollectorUtil.isNoTEmpty(families)) {
                Date oldBirthday = families.get(0).getBirthday();

                if (oldBirthday.compareTo(domain.getBirthday()) > 0) {
                    if (domain.getSex().equals("男")) {
                        domain.setMemberAlias(FamilyAliasNameEnum.BROTHER.getName());
                    } else {
                        domain.setMemberAlias(FamilyAliasNameEnum.SISTER.getName());
                    }

                    //更新其他孩子的昵称
                    updateChildAlias(families);

                } else {
                    if (domain.getSex().equals("男")) {
                        domain.setMemberAlias(FamilyAliasNameEnum.BROTHER_SMALL.getName());
                    } else {
                        domain.setMemberAlias(FamilyAliasNameEnum.SISTER_SMALL.getName());
                    }

                    Family f = families.get(0);

                    if (f.getSex().equals("男")) {
                        f.setMemberAlias(FamilyAliasNameEnum.BROTHER.getName());
                    } else {
                        f.setMemberAlias(FamilyAliasNameEnum.SISTER.getName());
                    }

                    saveOrUpdate(f);

                }

            } else {
                if (domain.getSex().equals("男")) {
                    domain.setMemberAlias(FamilyAliasNameEnum.BROTHER_SMALL.getName());
                } else {
                    domain.setMemberAlias(FamilyAliasNameEnum.SISTER_SMALL.getName());
                }
            }
        }

    }

    @Override
    public void afterSave(Family domain) throws Exception {
        if (ObjectUtil.notNull(domain.getBankAccount())) {
            BankAccount bankAccount = bankAccountService.get(domain.getBankAccount().getId());
            bankAccount.setFamily(new Family(domain.getId()));
            bankAccountService.saveOrUpdate(bankAccount);
        }
    }

    public void updateChildAlias(List<Family> families) throws Exception {
        for (Family family : families) {
            if (family.getSex().equals("男")) {
                family.setMemberAlias(FamilyAliasNameEnum.BROTHER_SMALL.getName());
            } else {
                family.setMemberAlias(FamilyAliasNameEnum.SISTER_SMALL.getName());
            }
            saveOrUpdate(family);
        }
    }

    @Override
    public void afterGet(Family domain) {

        long n = cn.hutool.core.date.DateUtil.betweenYear(domain.getBirthday(), DateUtil.getSysTime(), false);
        domain.setAge(n);

        if (ObjectUtil.notNull(domain.getBankAccount())) {
            Date date = domain.getBankAccount().getExpireDate();
            if (ObjectUtil.notNull(date)) {
                domain.getBankAccount().setExpireDateStr(DateUtil.getTime(date));
            }
        }

    }

    @Override
    public void afterList(List<Family> datas) throws Exception {
        String wxCode = WebUtil.getLoginUser().getUuid();
        Integer owner = getFamilyOwner(wxCode);
        for (Family data : datas) {
            if (owner.equals(1) ||
                    (StringUtil.isNotEmpty(data.getWxAccountCode()) &&
                            wxCode.equals(data.getWxAccountCode()))) {
                data.setCanAction(true);
            } else {
                data.setCanAction(false);
            }

            if (ObjectUtil.notNull(data.getBankAccount())) {
                Date expireDate = data.getBankAccount().getExpireDate();
                if (ObjectUtil.notNull(expireDate)) {
                    data.getBankAccount().setExpireDateStr(DateUtil.getTime(expireDate));
                }
            }
        }
    }


    @Override
    public void afterDelete(Family domain) throws Exception {
        List<Family> families = select(QueryDto.builder()
                .available()
                .addWhere("unicode='" + domain.getUnicode() + "'")
                .addWhere("member_alias not in ('爸爸','妈妈')")
                .addOrder("birthday")
                .build());


        if (CollectorUtil.isNoTEmpty(families)) {
            Family family = families.get(0);
            String boyAlias = families.size() > 1 ? FamilyAliasNameEnum.BROTHER.getName() : FamilyAliasNameEnum.BROTHER_SMALL.getName();
            String girlAlias = families.size() > 1 ? FamilyAliasNameEnum.SISTER.getName() : FamilyAliasNameEnum.SISTER_SMALL.getName();
            if (family.getSex().equals("男")) {
                family.setMemberAlias(boyAlias);
            } else {
                family.setMemberAlias(girlAlias);
            }
            saveOrUpdate(family);
        }

    }

    public Boolean checkHasParents() throws Exception {
        String unicode = WebUtil.getStringParam("faUnicode");
        Family family = get(QueryDto.builder()
                .available()
                .addWhere("unicode = '" + unicode + "'")
                .addWhere("member_alias in ('爸爸','妈妈')")
                .build());
        return ObjectUtil.notNull(family);
    }

    public Boolean checkHasChild() throws Exception {
        String unicode = WebUtil.getStringParam("faUnicode");
        Family family = get(QueryDto.builder()
                .available()
                .addWhere("unicode = '" + unicode + "'")
                .addWhere("member_alias not in ('爸爸','妈妈')")
                .build());
        return ObjectUtil.notNull(family);
    }

    public Map queryFamilyMember() throws Exception {
        List<Family> families = selectDomain();
        Family family = null;
        String unicode = WebUtil.getLoginUser().getUuid();
        if (CollectorUtil.isNoTEmpty(families)) {
            family = families.stream()
                    .filter(p -> ObjectUtil.notNull(p.getWxAccountCode()) &&
                            p.getWxAccountCode().equals(unicode))
                    .findFirst()
                    .orElse(null);
        }
        return MapUtil.builder()
                .add("families", families)
                .add("loginUser", family)
                .build();
    }
}
